package cn.felord.security.autoconfigure.handler;

import cn.felord.security.autoconfigure.SecureUser;
import cn.felord.security.autoconfigure.TokenGenerator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AccountStatusUserDetailsChecker;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.IOException;

/**
 * The type Login authentication success handler.
 *
 * @author felord.cn
 * @since 2021 /8/6 18:45
 */
public class LoginAuthenticationSuccessHandler extends ResponseWriter implements AuthenticationSuccessHandler {
    private final TokenGenerator<?> tokenGenerator;
    private final UserDetailsChecker userDetailsChecker = new AccountStatusUserDetailsChecker();
    private final UserDetailsService userDetailsService;

    /**
     * Instantiates a new Login authentication success handler.
     *
     * @param tokenGenerator     the token generator
     * @param userDetailsService the user details service
     */
    public LoginAuthenticationSuccessHandler(TokenGenerator<?> tokenGenerator, UserDetailsService userDetailsService) {
        this.tokenGenerator = tokenGenerator;
        this.userDetailsService = userDetailsService;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
        request.setAttribute("authentication", authentication);
        this.write(request, response);
    }

    protected SecurityRest<?> body(HttpServletRequest request) {
        Authentication authentication = (Authentication) request.getAttribute("authentication");
        String username = authentication.getName();
        SecureUser userDetails = (SecureUser) userDetailsService.loadUserByUsername(username);
        userDetailsChecker.check(userDetails);
        return SecurityRestBody.okData(this.tokenGenerator.tokenResponse(userDetails));
    }

}